﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace NHINDirect
{
    /// <summary>
    /// A very basic mime/entity writer
    /// The idea is that we are working off EXISTING WELL FORMED messages whose lexical structure we cannot change 
    /// (esp because of cryptography). Therefore, the assumption is that the orginal authoring application had done 
    /// the needful. 
    /// </summary>
    public class EntityWriter : IDisposable
    {        
        TextWriter m_writer;
        
        public EntityWriter(TextWriter writer)
        {
            this.SetWriter(writer);
        }
        
        public void SetWriter(TextWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException();
            }
            this.Close();
            this.m_writer = writer;
        }

        public void Write(HeaderCollection headers)
        {
            if (headers == null)
            {
                throw new ArgumentNullException();
            }
            
            foreach(Header header in headers)
            {
                this.Write(header);
            }
        }
        
        public void Write(Header header)
        {
            if (header == null)
            {
                throw new ArgumentNullException();
            }
            
            this.WriteLine(header.SourceText);
        }
        
        public void Write(Body body)
        {
            if (body == null)
            {
                throw new ArgumentNullException();
            }
            
            this.Write(body.SourceText);
        }
        
        public void WriteHeader(string name, string value)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException();
            }
            
            this.m_writer.Write(name);
            if (!string.IsNullOrEmpty(value))
            {
                this.m_writer.Write(Protocol.NameValueSeparator);
                this.m_writer.Write(value);
            }
            
            this.WriteCRLF();
        }
                
        public void WriteMimeBoundary(string boundary, bool isLast)
        {
            //
            // As per MIME spec, boundaries START with a CRLF
            //
            this.WriteCRLF();
            if (isLast)
            {
                this.WriteLine(Protocol.BoundarySeparator + boundary + Protocol.BoundarySeparator);
            }
            else
            {
                this.WriteLine(Protocol.BoundarySeparator + boundary);
            }
        }
        
        public void Write(StringSegment text)
        {
            for(int i = 0, count = text.Length; i < count; ++i)
            {
                this.m_writer.Write(text[i]);
            }
        }
                
        public void WriteLine(StringSegment text)
        {
            this.Write(text);
            this.WriteCRLF();
        }
        
        public void WriteLine(string text)
        {
            this.m_writer.Write(text);
            this.WriteCRLF();
        }
        
        public void WriteCRLF()
        {
            this.m_writer.Write(Protocol.CRLF);
        }        
        
        public void Close()
        {
            if (this.m_writer != null)
            {
                this.m_writer.Close();
                this.m_writer = null;
            }        
        }
        
        #region IDisposable Members

        public void Dispose()
        {
            this.Close();
        }

        #endregion
    }
}
